﻿#include "Common.h"

#include "ObjectPool.h"
static ObjectPool<Span> span;



void FreeList::Push(void* obj) {
	NextObj(obj) = _freeList;
	_freeList = obj;
	++_size;
}

void* FreeList::Pop() {
	void* obj = _freeList;
	_freeList = NextObj(_freeList);
	--_size;
	return obj;
}
bool FreeList::Empty() {
	return _freeList == nullptr;
}

//将一连串块接续挂在自由链表下
void FreeList::PushRange(void* start, void* end, size_t n) {
	NextObj(end) = _freeList;
	_freeList = start;

	_size += n;

}

void FreeList::PopRange(void*& start, void*& end, size_t n) {
	assert(n <= _size && n > 0);
	
	end = start = _freeList;
	for (size_t i = 0; i < n - 1; ++i) {
		end = NextObj(end);
	}
	_freeList = NextObj(end);
	NextObj(end) = nullptr;
	_size -= n;
}

//作用：将用户申请的内存字节数 bytes 向上对齐到 alignNum 的整数倍，
//确保分配的内存块满足对齐要求，从而减少内存碎片

size_t SizeClass::_RoundUp(size_t bytes, size_t align) {
	return (((bytes)+align - 1) & ~(align - 1));
}

size_t SizeClass::RoundUp(size_t bytes) {
	if (bytes <= 128) {
		return _RoundUp(bytes, 8);
	}
	else if (bytes <= 1024) {
		return _RoundUp(bytes, 16);
	}
	else if (bytes <= 8 * 1024) {
		return _RoundUp(bytes, 128);
	}
	else if (bytes <= 64 * 1024) {
		return _RoundUp(bytes, 1024);
	}
	else if (bytes <= 256 * 1024) {
		return _RoundUp(bytes, 8 * 1024);
	}
	else {
		return _RoundUp(bytes, 1 << PAGE_SHIFT);
	}
}


//根据对齐后的内存大小，
//快速定位该内存块所属的自由链表在哈希桶数组中的索引

size_t SizeClass::_Index(size_t bytes, size_t align_shift) {
	return ((bytes + (1 << align_shift) - 1) >> align_shift) - 1;
}


//计算自由链表在桶中的下标
size_t SizeClass::Index(size_t bytes) {
	//每个区间有多少个链
	static size_t group_array[4] = { 16, 56, 56, 56 };
	if (bytes <= 128) {
		return _Index(bytes, 3);
	}
	else if (bytes <= 1024) {
		return _Index(bytes - 128, 4) + group_array[0];
	}
	else if (bytes <= 8 * 1024) {
		return _Index(bytes - 1024, 7) + group_array[1] + group_array[0];
	}
	else if (bytes <= 64 * 1024) {
		return _Index(bytes - 8 * 1024, 10) + group_array[2] + group_array[1] +
			group_array[0];
	}
	else if (bytes <= 256 * 1024) {
		return _Index(bytes - 64 * 1024, 13) + group_array[3] + group_array[2] +
			group_array[1] + group_array[0];
	}
	else {
		return -1;
	}
}


// 一次从中心缓存获取多少个
size_t SizeClass::NumMoveSize(size_t size) {
	assert(size > 0);
	if (size == 0)
		return 0;

	//[2, 512], 一次批量移动多少个对象(慢启动的上限值)
	//小对象一次批量上限高
	//大对象一次批量上限低

	size_t num = MAX_BYTES / size;

	if (num < 2) {
		num = 2;
	}

	if (num > 512) {
		num = 512;
	}
	return num;
}
// 计算⼀次向系统获取⼏个⻚
// 单个对象 8byte
// ...
// 单个对象 256KB


size_t SizeClass::NumMovePage(size_t size)
{
	size_t num = NumMoveSize(size);
	size_t npage = num * size;
	npage >>= PAGE_SHIFT;
	if (npage == 0)
		npage = 1;
	return npage;
}

